home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / PASCAL / MISC_ROU / HFSSCN.PAS < prev    next >
Pascal/Delphi Source File  |  1989-12-02  |  9KB  |  272 lines

  1. PROGRAM HFSScan7 (Input, Output);
  2. {This program has been built from bits and pieces shamelessly lifted from
  3.  various Apple Tech Notes, mostly no.s 24, 66, and 68. I have put in a few
  4.  items of my own, mostly the glue between the tech notes.
  5.  
  6.  The intent of this pearl is to feel around HFS amd to devise a scheme for
  7.  locating a "beacon" file in ANY volume under any file system. Any file name
  8.  can be used (e.g., Desktop, Neil Konzen). At present the HFS scanner only
  9.  does the default volume but the MFS scanner does 'em all. Each MFS pass will
  10.  finally end with -43 when all files are exhausted. Don't worry about it.
  11.  
  12.  This is a "work in progress" but it is offered in response to those folks who
  13.  have been asking about HFS and how to find a file. What is missing most
  14.  prominently (aside from good coding technique and design!) is the traverse
  15.  down the DirID tree once the "beacon" is found - with this and the volume name
  16.  one has... a complete pathname! As the old text book copout goes: we leave
  17.  this as an exercise for the student...
  18.  
  19.  Oh, about the "$I HardDisk-20:TMLPascal:relFldr:etc."; those are my names
  20.  on my HardDisk-20 for my TML files. Change them to match your system.
  21.  
  22.  Cheers and encouragement, praise, good words may be sent to me - boos, jeers,
  23.  and derision may be sent to the nearest bit-bucket. Enjoy!
  24.  
  25.  Signed,
  26.  Rick Emerson (76254,421)
  27.  for The System Support Group,
  28.  "The folks to call when you don't
  29.  understand it all."
  30.  
  31.  Notice: This work is offered "as is" and no warranty of any sort is expressly
  32.  stated or implied.
  33. }
  34.  
  35. {$I HardDisk-20:TMLPascal:relFldr:MemTypes.ipas    }
  36. {$I HardDisk-20:TMLPascal:relFldr:QuickDraw.ipas    }
  37. {$I HardDisk-20:TMLPascal:relFldr:OSIntf.ipas    }
  38. {$I HardDisk-20:TMLPascal:relFldr:HFS.ipas    }
  39. {$I HardDisk-20:TMLPascal:relFldr:ToolIntf.ipas    }
  40. {$I HardDisk-20:TMLPascal:relFldr:PackIntf.ipas    }
  41.  
  42. VAR
  43.     targetString:    Str255;
  44.     targetStrPtr:    StringPtr;
  45.     myOSErr:            OSErr;
  46.     whichVol:            INTEGER;
  47.     whichFile:        INTEGER;
  48.     myVolRef:            INTEGER;
  49.     myVolName:        Str255;
  50.     myPathname:        Str255;
  51.     isamErr:            INTEGER;
  52.     volumeOK:            BOOLEAN;
  53.     fileOK:            BOOLEAN;
  54.     filePB:             ParamBlockRec;
  55.     homeNamePtr:        StringPtr;
  56.     homeVolRefNo:    INTEGER;
  57.     homeRefNum:        INTEGER;
  58.     dummy:            CHAR;
  59.     dummyStr:            Str255;
  60.     dummyPtr:            StringPtr;
  61.  
  62. FUNCTION GetIndVolume (whichVol:INTEGER;
  63.                             VAR volName: Str255;
  64.                             VAR volRef: INTEGER): OSErr;
  65. {*
  66.  * GetIndVolume: return the name and volume reference number of a volume,
  67.  * specified by whichVol. From Macintosh Technote #24 by Bryan Stearns.
  68.  *}
  69.  
  70. VAR
  71.     volPB: ParamBlockRec;
  72.     anErr: OSErr;
  73.  
  74. BEGIN
  75.     WITH volPB DO BEGIN    {makes it easier to fill fields in!}
  76.         ioCompletion := NIL;
  77.         ioNamePtr := @volName;    {make sure it returns the name}
  78.         ioVRefNum := 0;    {to determine which volume}
  79.         ioVolIndex := whichVol;    {use this to determine the volume}
  80.         anErr := PBGetVInfo(@volPB,FALSE);     {do it (FALSE = synchronously)}
  81.         GetIndVolume := anErr;    {return error code}
  82.         IF anErr = noErr THEN BEGIN     {if no error occurred }
  83.             volRef := ioVRefNum;    {  return the vol info}
  84.         END; {if no error}
  85.     END; {with}
  86. END {GetIndVolume};
  87.  
  88. PROCEDURE EnumerShell(DirIDToSearch:    LongInt);
  89.     {From Macintosh Technote #68 by Jim Friedlander.}
  90.  
  91. VAR
  92.       myCPB: CInfoPBRec;
  93.       err: OSErr;  
  94.       myWDPB: WDPBRec;
  95.       TotalFiles,TotalDirectories: INTEGER;
  96.       fName:    Str255;
  97.  
  98.  
  99.  
  100. PROCEDURE EnumerateCatalog(dirIDToSearch: LongInt);
  101.  
  102. VAR
  103.   index:    INTEGER;  
  104.  
  105. BEGIN {EnumerateCatalog}
  106.     index:= 1;
  107.     REPEAT
  108.         FName:= '';  {nil out name}
  109.         myCPB.ioCompletion := NIL;
  110.         myCPB.ioVRefNum := myWDPB.ioVRefNum;    {Look in current working vol}
  111.         myCPB.ioFDirIndex:= index;
  112.         myCPB.ioDrDirID:= dirIDToSearch; {we need to do this every time through}
  113.  
  114.         err:= PBGetCatInfo(@myCPB,FALSE);
  115.  
  116.         IF err = noErr THEN 
  117.             IF BitTst(@myCPB.ioFlAttrib,3) THEN
  118.             BEGIN {directory bit set}
  119.                 TotalDirectories:=TotalDirectories+1;
  120.                 EnumerateCatalog(myCPB.ioDrDirID);
  121.                 err:= 0;  {clear error return on way back}
  122.             END
  123.             ELSE
  124.             BEGIN{directory bit cleared - we have a file}
  125.                 TotalFiles:= TotalFiles + 1;
  126.                 IF EqualString (myCPB.ioNamePtr^, targetString, FALSE, FALSE) THEN
  127.                 BEGIN
  128.                     Write (myCPB.ioNamePtr^, ' and ', targetString, ' match! ');
  129.                     WriteLn (' myCPB.ioVRefNum = ', myCPB.ioVRefNum);
  130.                     WriteLn (' myCPB.ioFlNum = ', myCPB.ioFlNum);
  131.                 END {IF};
  132.             END {IF};
  133.         index:= index + 1;
  134.     UNTIL err <> noErr;
  135. END {EnumerateCatalog};
  136.  
  137. BEGIN {EnumerShell}
  138.    TotalFiles:= 0;
  139.     TotalDirectories:= 0;
  140.     fName:= '';  {nil out name}
  141.     myWDPB.ioCompletion := NIL;    {Set up a default vol & dir...}
  142.     myWDPB.ioNamePtr := NIL;        {...so we have a definite starting...}
  143.     myWDPB.ioVRefNum := 0;            {...point to search from.}
  144.     myWDPB.ioWDDirID := 0;
  145.     err := PBHSetVol (@myWDPB, FALSE);    {Make us a default}
  146.     dummyStr := '';
  147.     dummyPtr := @dummyStr;
  148.     myWDPB.ioCompletion := NIL;
  149.     myWDPB.ioNamePtr := dummyPtr;    {Demand a name by using a null string}
  150.     err:= PBHGetVol(@myWDPB,FALSE);        {get the default volume}
  151.     WriteLn ('Starting with vol ->', myWDPB.ioNamePtr^, '<- & WDVRefNum =',
  152.                 myWDPB.ioWDVRefNum);
  153.     WriteLn ('ioVRefNum = ', myWDPB.ioVRefNum);
  154.  
  155.     WITH MyCPB DO BEGIN
  156.         iocompletion:= NIL;
  157.         ioNamePtr:= @FName;
  158.         ioVRefNum:= myWDPB.ioVRefNum;      {For now this is the default vol...}
  159.                                                 {...change it to scout other vols}
  160.     END {WITH};
  161.     EnumerateCatalog(2);{DirID 2, the root level}
  162.     Write (totalDirectories, ' directories searched and ');
  163.     WriteLn (totalFiles, ' files searched.');
  164. END {EnumerShell};
  165.  
  166. FUNCTION IsItHFS : BOOLEAN;
  167.     {From Macintosh Technote #66 by Jim Friedlander.}
  168.  
  169. CONST
  170.     FSFCBLen=    $3F6;    {address of the low-memory global}
  171.  
  172. VAR
  173.     HFS:    ^INTEGER;
  174.  
  175. BEGIN
  176.     HFS:= POINTER(FSFCBLen);
  177.     IF HFS^ > 0 THEN
  178.         IsItHFS := TRUE    {we're running HFS}
  179.     ELSE
  180.         IsItHFS := FALSE;    {we're running MFS}
  181. END {IsItHFS};
  182.  
  183. BEGIN
  184.     targetString := 'HomeBeacon';    {Can we find this file somewhere?}
  185.     targetStrPtr := @targetString;
  186.     whichVol := 1;
  187.     volumeOK := TRUE;
  188.     WHILE volumeOK DO
  189.     BEGIN
  190.         myOSErr := GetIndVolume (whichVol, myVolName, myVolRef);
  191.         IF (myOSErr = nsvErr) THEN
  192.             volumeOK := FALSE
  193.         ELSE
  194.         BEGIN
  195.             Write ('ioVolIndex = ', whichVol, ' volName ->', myVolName, '<- ');
  196.             WriteLn (' volRef = ', myVolRef);
  197.             whichVol := whichVol + 1;
  198.         END {IF};
  199.     END {WHILE};
  200.     IF IsItHFS THEN BEGIN
  201.         WriteLn ('This is coming to you via HFS!');
  202.         EnumerShell(0);    {Go look for truth, beauty and... HomerBeacon?}
  203.     END
  204.     ELSE
  205.     BEGIN
  206.         WriteLn ('This has all the earmarks of MFS.');
  207.         dummyStr := '';
  208.         dummyPtr := @dummyStr;
  209.         whichVol := 1;
  210.         volumeOK := TRUE;
  211.         WHILE volumeOK DO    {Page through the vols looking for HomerBeacon}
  212.         BEGIN
  213.             myOSErr := GetIndVolume (whichVol, myVolName, myVolRef);
  214.             IF (myOSErr = nsvErr) THEN
  215.                 volumeOK := FALSE
  216.             ELSE
  217.             BEGIN
  218.                 whichFile := 1;    {Page through the files looking for HomerBeacon}
  219.                 fileOK := TRUE;
  220.                 WHILE fileOK DO
  221.                 BEGIN
  222.                     WITH filePB DO
  223.                     BEGIN
  224.                         ioCompletion := NIL;
  225.                         ioVRefNum := myVolRef;
  226.                         ioNamePtr := dummyPtr;    {Clear name pointer}
  227.                         ioFDirIndex := whichFile;
  228.                         ioFVersNum := 0;
  229.                         myOSErr := PBGetFInfo(@filePB,FALSE);    {FALSE = synchronously}
  230.                         IF (myOSErr = noErr) THEN
  231.                         BEGIN
  232.                             IF (targetStrPtr^=ioNamePtr^) THEN
  233.                             BEGIN
  234.                                 homeNamePtr := ioNamePtr;    {Mark it for...}
  235.                                 homeVolRefNo := ioVRefNum;    {...later recall}
  236.                                 WriteLn (targetStrPtr^, ' and ', ioNamePtr^,
  237.                                             ' matched up!');
  238.                                 ioCompletion := NIL;    {Do an open to...}
  239.                                 ioNamePtr := homeNamePtr;    {...prove we really found...}
  240.                                 ioVRefNum := homeVolRefNo;    {...the file in MFS land}
  241.                                 ioFVersNum := 0;    {Per Mike Cohen & IM}
  242.                                 ioPermssn := 0;    {Allow whatever is OK now}
  243.                                 ioMisc := NIL;    {Use vol buffer}
  244.                                 myOSErr := PBOpen(@filePB,FALSE);
  245.                                 IF (myOSErr = noErr) THEN
  246.                                 BEGIN
  247.                                     WriteLn ('File opened OK');
  248.                                     homeRefNum := ioRefNum;
  249.                                     ioCompletion := NIL;    {Nice, now put it back!}
  250.                                     ioRefNum := homeRefNum;
  251.                                     myOSErr := PBClose (@filePB, FALSE);
  252.                                     WriteLn ('After close OSErr = ', myOSErr);
  253.                                 END
  254.                                 ELSE
  255.                                 BEGIN    {Close, but no luck - You lose}
  256.                                     WriteLn ('Unable to open ', ioNamePtr^);
  257.                                     WriteLn ('OSErr = ', myOSErr);
  258.                                 END {IF};
  259.                             END
  260.                             ELSE
  261.                                 WriteLn (' ');
  262.                             whichFile := whichFile + 1;
  263.                         END {IF};
  264.                     END {WHILE};
  265.                 END {WITH};
  266.                 whichVol := whichVol + 1;
  267.             END {IF};
  268.         END {WHILE};
  269.     END {IF};
  270.     WriteLn ('Search done - Hit RETURN to quit');
  271.     ReadLn (dummy);    {Wait for this to be read}
  272. END {HFSScan}.